﻿using System.Net;
using Microsoft.ResourceManagement.Client;
using System;
using Microsoft.ResourceManagement.ObjectModel;
using Microsoft.ResourceManagement.ObjectModel.ResourceTypes;

class DefaultClientExample {

    /// <summary>
    /// The credentials to use to run the examples.
    /// </summary>
    NetworkCredential credentials;

    /// <summary>
    /// Constructor.
    /// </summary>
    /// <param name="username">The user name.</param>
    /// <param name="pwd">The password.</param>
    /// <param name="domain">The domain.</param>
    public DefaultClientExample(string username, string pwd, string domain) {
        credentials = new NetworkCredential(username, pwd, domain);
    }

    /// <summary>
    /// Basic client usage.
    /// </summary>
    public void DefaultClientBaseUsage() {

        // Create a new DefaultClient using all the default contracts.
        // Since the DefaultClient class implements the IDisposable interface,
        // we can use the using statement to make sure that resources will be
        // properly disposed (http://msdn.microsoft.com/en-us/library/yh598w02%28VS.80%29.aspx).
        using (DefaultClient client = new DefaultClient()) {

            // Explicitly set the client credentials if needed. 
            // By default, the credentials of the user running the application
            // will be used.
            client.ClientCredential = this.credentials;

            // IMPORTANT: Refresh the schema.
            // This operation allows the request and resource factories used by
            // the client to use the correct schema information, thus knowing
            // for example which attributes are multi valued or single valued.
            // Not refreshing the schema can cause some difficult to debug
            // incorrect behaviors.
            client.RefreshSchema();

            // do something with the client...

        } // ... and release the resources (close the connections) as the using
        // block scope ends.
    }

    /// <summary>
    /// Request approval
    /// </summary>
    public void ApproveAllRequests() {

        using (DefaultClient client = new DefaultClient()) {
            // set credentials and refresh schema
            client.ClientCredential = this.credentials;
            client.RefreshSchema();

            // Enumerate all the approvals.
            // The FIM service only returns approvals we can act on with current
            // credentials
            foreach (RmResource resource in client.Enumerate(string.Format("/Approval[ApprovalStatus='Pending']"))) {

                RmApproval approval = resource as RmApproval;
                if (approval != null) {
                    Console.WriteLine("Approving request {0} on endpoint {1}: ", approval.ObjectID, approval.ApprovalEndpointAddress);
                    try {
                        // Approve the request using the default approval 
                        // endpoint configuration (ServiceMultipleTokenBinding_ResourceFactory)
                        // true = approve, false = reject
                        client.Approve(approval, true);
                        Console.WriteLine("Success.");
                    } catch (Exception exc) {
                        Console.WriteLine("Failed: {0}", exc);
                    }
                }
            }
            Console.ReadLine();
        }
    }

    /// <summary>
    /// Modify a person's attribute
    /// </summary>
    public void ModifyPerson() {
        // This example shows the basic steps to modify a resource.
        using (DefaultClient client = new DefaultClient()) {
            // set credentials and refresh schema
            client.ClientCredential = this.credentials;
            client.RefreshSchema();
            // get the person(s) object(s) to modify
            foreach (RmPerson person in client.Enumerate("/Person[DisplayName='Gandalf the Grey']")) {
                // create the object to track changes to the resource
                RmResourceChanges changes = new RmResourceChanges(person);
                try {
                    // change something in the resource
                    person.DisplayName = "Gandalf the White";
                    // modify the resource on the server
                    client.Put(changes);
                    // the operation succeeded: accept the changes.
                    changes.AcceptChanges();
                    // NOTE: after calling AcceptChanges the RmResourceChanges 
                    // object does not contain any more changes to propagate to
                    // the server.
                } catch {
                    // an error occurred, so the resource was not modified; 
                    // rollback the changes.
                    changes.DiscardChanges();
                    throw;
                }
            }
        }
    }

}
